using System;
using System.Collections.Generic;
using System.Data;

using PMServiceDesk.DataType;
using PMServiceDesk.Utils.ManejoDatos;

namespace PMServiceDesk.DataAccess
{
    public class ProyectoData
    {
        #region Variables

        private string _select;
        private string _join;
        private string _where;
        private int _totalRegistros = 0;

        private Dictionary<string, object> _parametrosConsulta;

        #endregion

        #region Propiedades

        protected string Where
        {
            get
            {
                if (_where == "") return "";

                return "WHERE " + _where.Substring(3);
            }
        }

        #endregion

        #region Constructores

        public ProyectoData()
        {
            this._limpiarConsulta();
        }

        #endregion

        #region Metodos

        private void _limpiarConsulta()
        {
            _select = "";
            _join = "";
            _where = "";
            _parametrosConsulta = new Dictionary<string, object>();
        }

        private DataUtil _consultaDataReader(int paginaActual = 0, int cantidadMostrar = 0, string orderBy = "")
        {
            DataUtil data = null;

            if(paginaActual==0)
                data = new DataUtil(TypeDataBase.PMServiceDesk, CommandType.Text, _select + _join + this.Where + orderBy,_parametrosConsulta);
            else
                data = DataReader.ReturnPagingReader(TypeDataBase.PMServiceDesk, _select, _join, this.Where, this._parametrosConsulta, paginaActual, cantidadMostrar, orderBy, ref _totalRegistros);

            this._limpiarConsulta();

            return data;
        }

        public void Grabar(ProyectoType proyecto)
        {
            using (DataUtil d = this._grabar())
            {
                d.AddParameter("@ID", (proyecto.Id == null ? "0" : proyecto.Id));
                d.AddParameter("@ORIGENID", proyecto.OrigenId);
                d.AddParameter("@MONEDAID", proyecto.MonedaId);
                d.AddParameter("@USUARIOJEFEPROYECTOID", proyecto.UsuarioJefeProyectoId);
                d.AddParameter("@ESTADOID", proyecto.EstadoId);
                d.AddParameter("@NOMBRE", proyecto.Nombre);
                d.AddParameter("@DESCRIPCION", proyecto.Descripcion);
                d.AddParameter("@FECHAINICIOESTIMADO",ConvertFormat.Char_To_DateOrNull(proyecto.FechaInicioEstimado));
                d.AddParameter("@FECHAFINESTIMADO", ConvertFormat.Char_To_DateOrNull(proyecto.FechaFinEstimado));
                d.AddParameter("@FECHAINICIOREAL", ConvertFormat.Char_To_DateOrNull(proyecto.FechaInicioReal));
                d.AddParameter("@FECHAFINREAL", ConvertFormat.Char_To_DateOrNull(proyecto.FechaFinReal));

                proyecto.Id = d.ExecuteScalar(true).ToString();
            }
        }

        public ProyectoType Cargar()
        {
            List<ProyectoType> l = this.CargarLista();

            if (l.Count == 0) return null;

            return l[0];
        }

        public List<ProyectoType> CargarLista()
        {
            List<ProyectoType> l = new List<ProyectoType>();

            using (DataUtil d = this._consultaCargar())
                using (IDataReader r = d.ExecuteReader())
                {
                    ProyectoType o = null;

                    while (r.Read())
                    {
                        o = new ProyectoType();

                        o.Id = r.GetValue(d.GetOrdinalReader("ID")).ToString();
                        o.OrigenId = r.GetValue(d.GetOrdinalReader("ORIGENID")).ToString();
                        o.Origen = r.GetValue(d.GetOrdinalReader("ORIGEN")).ToString();
                        o.MonedaId = r.GetValue(d.GetOrdinalReader("MONEDAID")).ToString();
                        o.Moneda = r.GetValue(d.GetOrdinalReader("MONEDA")).ToString();
                        o.SimboloMoneda = r.GetValue(d.GetOrdinalReader("SIMBOLOMONEDA")).ToString();
                        o.UsuarioJefeProyectoId = r.GetValue(d.GetOrdinalReader("USUARIOJEFEPROYECTOID")).ToString();
                        o.UsuarioJefeProyecto = r.GetValue(d.GetOrdinalReader("USUARIOJEFEPROYECTO")).ToString();
                        o.EstadoId = r.GetValue(d.GetOrdinalReader("ESTADOID")).ToString();
                        o.Estado = r.GetValue(d.GetOrdinalReader("ESTADO")).ToString();
                        o.Nombre = r.GetValue(d.GetOrdinalReader("NOMBRE")).ToString();
                        o.Descripcion = r.GetValue(d.GetOrdinalReader("DESCRIPCION")).ToString();
                        o.FechaInicioEstimado =  ConvertFormat.Date_To_Char(r.GetValue(d.GetOrdinalReader("FECHAINICIOESTIMADO")));
                        o.FechaFinEstimado = ConvertFormat.Date_To_Char(r.GetValue(d.GetOrdinalReader("FECHAFINESTIMADO")));
                        o.FechaInicioReal = ConvertFormat.Date_To_Char(r.GetValue(d.GetOrdinalReader("FECHAINICIOREAL")));
                        o.FechaFinReal = ConvertFormat.Date_To_Char(r.GetValue(d.GetOrdinalReader("FECHAFINREAL")));

                        l.Add(o);
                    }
                }

            return l;
        }

        public List<ProyectoType> CargarListaVista(int paginaActual = 0, int cantidadMostrar = 0, string orderBy = "")
        {
            List<ProyectoType> l = new List<ProyectoType>();

            using (DataUtil d = this._consultaCargarVista(paginaActual, cantidadMostrar,orderBy))
                using (IDataReader r = d.ExecuteReader())
                {
                    ProyectoType o = null;

                    while (r.Read())
                    {
                        o = new ProyectoType();

                        o.Id = r.GetValue(d.GetOrdinalReader("ID")).ToString();
                        o.OrigenId = r.GetValue(d.GetOrdinalReader("ORIGENID")).ToString();
                        o.Origen = r.GetValue(d.GetOrdinalReader("ORIGEN")).ToString();
                        o.MonedaId = r.GetValue(d.GetOrdinalReader("MONEDAID")).ToString();
                        o.Moneda = r.GetValue(d.GetOrdinalReader("MONEDA")).ToString();
                        o.UsuarioJefeProyectoId = r.GetValue(d.GetOrdinalReader("USUARIOJEFEPROYECTOID")).ToString();
                        o.UsuarioJefeProyecto = r.GetValue(d.GetOrdinalReader("USUARIOJEFEPROYECTO")).ToString();
                        o.EstadoId = r.GetValue(d.GetOrdinalReader("ESTADOID")).ToString();
                        o.Estado = r.GetValue(d.GetOrdinalReader("ESTADO")).ToString();
                        o.Nombre = r.GetValue(d.GetOrdinalReader("NOMBRE")).ToString();
                        o.Descripcion = r.GetValue(d.GetOrdinalReader("DESCRIPCION")).ToString();
                        o.FechaInicioEstimado = ConvertFormat.Date_To_Char(r.GetValue(d.GetOrdinalReader("FECHAINICIOESTIMADO")));
                        o.FechaFinEstimado = ConvertFormat.Date_To_Char(r.GetValue(d.GetOrdinalReader("FECHAFINESTIMADO")));
                        o.FechaInicioReal = ConvertFormat.Date_To_Char(r.GetValue(d.GetOrdinalReader("FECHAINICIOREAL")));
                        o.FechaFinReal = ConvertFormat.Date_To_Char(r.GetValue(d.GetOrdinalReader("FECHAFINREAL")));

                        l.Add(o);
                    }
                }

            if (l.Count <= _totalRegistros) l.Capacity = _totalRegistros;

            return l;
        }

        #endregion

        #region SQL

        private DataUtil _grabar()
        {
            string sql = @"IF(NOT EXISTS(SELECT 1 FROM PROYECTO WHERE ID=@ID)) 
                           BEGIN
                               INSERT INTO PROYECTO
                               (
                                   ORIGENID
                                  ,MONEDAID
                                  ,USUARIOJEFEPROYECTOID
                                  ,ESTADOID
                                  ,NOMBRE
                                  ,DESCRIPCION
                                  ,FECHAINICIOESTIMADO
                                  ,FECHAFINESTIMADO
                                  ,FECHAINICIOREAL
                                  ,FECHAFINREAL
                               )
                               VALUES
                               (
                                   @ORIGENID
                                  ,@MONEDAID
                                  ,@USUARIOJEFEPROYECTOID
                                  ,@ESTADOID
                                  ,@NOMBRE
                                  ,@DESCRIPCION
                                  ,@FECHAINICIOESTIMADO
                                  ,@FECHAFINESTIMADO
                                  ,@FECHAINICIOREAL
                                  ,@FECHAFINREAL
                               )

                               SELECT @@IDENTITY
                           END
                           ELSE
                           BEGIN
                               UPDATE PROYECTO SET
                               ORIGENID=@ORIGENID
                              ,MONEDAID=@MONEDAID
                              ,USUARIOJEFEPROYECTOID=@USUARIOJEFEPROYECTOID
                              ,ESTADOID=@ESTADOID
                              ,NOMBRE=@NOMBRE
                              ,DESCRIPCION=@DESCRIPCION
                              ,FECHAINICIOESTIMADO=@FECHAINICIOESTIMADO
                              ,FECHAFINESTIMADO=@FECHAFINESTIMADO
                              ,FECHAINICIOREAL=@FECHAINICIOREAL
                              ,FECHAFINREAL=@FECHAFINREAL
                               WHERE ID=@ID

                               SELECT @ID
                           END";

            return new DataUtil(TypeDataBase.PMServiceDesk, CommandType.Text, sql);
        }

        private DataUtil _consultaCargar()
        {
            _select = @"SELECT
                        PR.ID												[ID]
                        ,PR.ORIGENID										[ORIGENID]
                        ,ORI.NOMBRE											[ORIGEN]
                        ,PR.MONEDAID										[MONEDAID]
                        ,MON.NOMBRE											[MONEDA]
                        ,MON.ABREVIATURA							    [SIMBOLOMONEDA]
                        ,PR.USUARIOJEFEPROYECTOID							[USUARIOJEFEPROYECTOID]
                        ,REC.NOMBRE											[USUARIOJEFEPROYECTO]
                        ,PR.ESTADOID										[ESTADOID]
                        ,ESTPROY.NOMBRE										[ESTADO]
                        ,PR.NOMBRE											[NOMBRE]
                        ,PR.DESCRIPCION										[DESCRIPCION]
                        ,PR.FECHAINICIOESTIMADO     	                    [FECHAINICIOESTIMADO]
                        ,PR.FECHAFINESTIMADO		                        [FECHAFINESTIMADO]
                        ,PR.FECHAINICIOREAL		                            [FECHAINICIOREAL]
                        ,PR.FECHAFINREAL			                        [FECHAFINREAL]
                        ";

            _join = @"FROM DBO.PROYECTO [PR]  
                        INNER JOIN USUARIO [USU] ON PR.USUARIOJEFEPROYECTOID = USU.ID
                        INNER JOIN USUARIORECURSO [USR] ON USU.ID = USR.USUARIOID
                        INNER JOIN RECURSO [REC] ON USR.RECURSOID = REC.ID AND PR.ID = REC.PROYECTOID
                        INNER JOIN ESTADO [ESTPROY] ON PR.ESTADOID=ESTPROY.ID
                        INNER JOIN PARAMETRO [ORI] ON PR.ORIGENID = ORI.ID 
                        INNER JOIN PARAMETRO [MON] ON PR.MONEDAID = MON.ID 
                      ";

            return this._consultaDataReader();
        }

        private DataUtil _consultaCargarVista(int paginaActual = 0, int cantidadMostrar = 0, string orderBy = "")
        {
            _select = @"SELECT
                        PR.ID												[ID]
                        ,PR.ORIGENID										[ORIGENID]
                        ,ORI.Nombre											[ORIGEN]
                        ,PR.MONEDAID										[MONEDAID]
                        ,MON.Nombre											[MONEDA]
                        ,PR.USUARIOJEFEPROYECTOID							[USUARIOJEFEPROYECTOID]
                        ,Rec.Nombre											[USUARIOJEFEPROYECTO]
                        ,PR.ESTADOID										[ESTADOID]
                        ,EstProy.Nombre										[ESTADO]
                        ,PR.NOMBRE											[NOMBRE]
                        ,PR.DESCRIPCION										[DESCRIPCION]
                        ,PR.FECHAINICIOESTIMADO     	                    [FECHAINICIOESTIMADO]
                        ,PR.FECHAFINESTIMADO		                        [FECHAFINESTIMADO]
                        ,PR.FECHAINICIOREAL		                            [FECHAINICIOREAL]
                        ,PR.FECHAFINREAL			                        [FECHAFINREAL]
                        ";

            _join = @"FROM DBO.PROYECTO [PR]  
                        INNER JOIN USUARIO [USU] ON PR.USUARIOJEFEPROYECTOID = USU.ID
                        INNER JOIN USUARIORECURSO [USR] ON USU.ID = USR.USUARIOID
                        INNER JOIN RECURSO [REC] ON USR.RECURSOID = REC.ID AND PR.ID = REC.PROYECTOID
                        INNER JOIN ESTADO [ESTPROY] ON PR.ESTADOID=ESTPROY.ID
                        INNER JOIN PARAMETRO [ORI] ON PR.ORIGENID = ORI.ID 
                        INNER JOIN PARAMETRO [MON] ON PR.MONEDAID = MON.ID 
                      ";

            return this._consultaDataReader(paginaActual, cantidadMostrar, orderBy);
        }

        public void FiltrarPorId(string id)
        {
            _where += @"AND PR.ID=@ID
                                 ";

            _parametrosConsulta.Add("@ID", id);
        }
        public void FiltrarPorOrigenId(string origenId)
        {
            _where += @"AND PR.ORIGENID=@ORIGENID
                                 ";

            _parametrosConsulta.Add("@ORIGENID", origenId);
        }
        public void FiltrarPorMonedaId(string monedaId)
        {
            _where += @"AND PR.MONEDAID=@MONEDAID
                                 ";

            _parametrosConsulta.Add("@MONEDAID", monedaId);
        }
        public void FiltrarPorUsuarioJefeProyectoId(string usuarioJefeProyectoId)
        {
            _where += @"AND PR.USUARIOJEFEPROYECTOID=@USUARIOJEFEPROYECTOID
                                 ";

            _parametrosConsulta.Add("@USUARIOJEFEPROYECTOID", usuarioJefeProyectoId);
        }
        public void FiltrarPorEstadoId(string estadoId)
        {
            _where += @"AND PR.ESTADOID=@ESTADOID
                                 ";

            _parametrosConsulta.Add("@ESTADOID", estadoId);
        }
        public void FiltrarPorNombre(string nombre)
        {
            _where += @"AND PR.NOMBRE LIKE '%' + @NOMBRE + '%'
                                 ";

            _parametrosConsulta.Add("@NOMBRE", nombre);
        }
        public void FiltrarPorDescripcion(string descripcion)
        {
            _where += @"AND PR.DESCRIPCION=@DESCRIPCION
                                 ";

            _parametrosConsulta.Add("@DESCRIPCION", descripcion);
        }
        public void FiltrarPorFechaInicioEstimado(DateTime fechaDesde, DateTime fechaHasta)
        {
            _where += @"AND
                        ( 
                            PR.FECHAINICIOESTIMADO >= @FECHADESDE
                            AND 
                            PR.FECHAINICIOESTIMADO < @FECHAHASTA
                        )
                        ";

            _parametrosConsulta.Add("@FECHADESDE", fechaDesde);
            _parametrosConsulta.Add("@FECHAHASTA", fechaHasta);
        }
        public void FiltrarPorFechaFinEstimado(DateTime fechaDesde, DateTime fechaHasta)
        {
            _where += @"AND
                        ( 
                            PR.FECHAFINESTIMADO>= @FECHADESDE
                            AND 
                            PR.FECHAFINESTIMADO < @FECHAHASTA
                        )
                        ";

            _parametrosConsulta.Add("@FECHADESDE", fechaDesde);
            _parametrosConsulta.Add("@FECHAHASTA", fechaHasta);
        }

        public void FiltrarPorFechaInicioReal(DateTime fechaDesde, DateTime fechaHasta)
        {
            _where += @"AND
                        ( 
                            PR.FECHAINICIOREAL >= @FECHADESDE
                            AND 
                            PR.FECHAINICIOREAL < @FECHAHASTA
                        )
                        ";

            _parametrosConsulta.Add("@FECHADESDE", fechaDesde);
            _parametrosConsulta.Add("@FECHAHASTA", fechaHasta);
        }
        public void FiltrarPorFechaFinReal(DateTime fechaDesde, DateTime fechaHasta)
        {
            _where += @"AND
                        ( 
                            PR.FECHAFINREAL >= @FECHADESDE
                            AND 
                            PR.FECHAFINREAL < @FECHAHASTA
                        )
                        ";

            _parametrosConsulta.Add("@FECHADESDE", fechaDesde);
            _parametrosConsulta.Add("@FECHAHASTA", fechaHasta);
        }

        #endregion
    }
}
